﻿using iTextSharp.text;
using iTextSharp.text.pdf;
using Ortodoctor.Componentes;
using Ortodoctor.modelo;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Ortodoctor.Funcionario
{
    public partial class Relatorios : System.Web.UI.Page
    {
        private const int pageCount = 47;
        iTextSharp.text.Font font = iTextSharp.text.FontFactory.GetFont("Times New Roman", 10, iTextSharp.text.Font.NORMAL, new BaseColor(Color.Black));

        protected void Page_Load(object sender, EventArgs e)
        {
            if (Session["USUARIO"] == null)
                Response.Redirect("Login.aspx");

            ModeloClinica modelo = new ModeloClinica();
            DataTable dt = modelo.getAll();
            dt.DefaultView.Sort = "[cidade] ASC";
            dt = dt.DefaultView.ToTable();

            clinicas.Items.Clear();
            clinicaParcela.Items.Clear();
            ClinicaSelect.Items.Clear();
            dentistaSelect.Items.Clear();
            pacienteParcela.Items.Clear();
            pacientes.Items.Clear();

            clinicaParcela.Items.Add(new System.Web.UI.WebControls.ListItem("Todos", "-999"));
            ClinicaSelect.Items.Add(new System.Web.UI.WebControls.ListItem("Todos", "-999"));
            clinicas.Items.Add(new System.Web.UI.WebControls.ListItem("Todos", "-999"));
            dentistaSelect.Items.Add(new System.Web.UI.WebControls.ListItem("Todos", "-999"));
            pacienteParcela.Items.Add(new System.Web.UI.WebControls.ListItem("Todos", "-999"));
            pacientes.Items.Add(new System.Web.UI.WebControls.ListItem("Todos", "-999"));

            foreach (DataRow dr in dt.Rows)
            {
                clinicaParcela.Items.Add(new System.Web.UI.WebControls.ListItem(dr["cidade"].ToString(), dr["id_clinica"].ToString()));
                ClinicaSelect.Items.Add(new System.Web.UI.WebControls.ListItem(dr["cidade"].ToString(), dr["id_clinica"].ToString()));
                clinicas.Items.Add(new System.Web.UI.WebControls.ListItem(dr["cidade"].ToString(), dr["id_clinica"].ToString()));
            }

            modeloDentista md = new modeloDentista();
            DataTable dtmd = md.getAll();

            foreach (DataRow dr in dtmd.Rows)
            {
                dentistaSelect.Items.Add(new System.Web.UI.WebControls.ListItem(dr["nome"].ToString(), dr["id_funcionario"].ToString()));
            }

            modeloCliente modeloCliente = new modeloCliente();
            DataTable cliente = modeloCliente.getAll();

            foreach (DataRow dr in cliente.Rows)
            {
                pacienteParcela.Items.Add(new System.Web.UI.WebControls.ListItem(dr["nome"].ToString(), dr["id_cliente"].ToString()));
                pacientes.Items.Add(new System.Web.UI.WebControls.ListItem(dr["nome"].ToString(), dr["id_cliente"].ToString()));
            }
        }

        public void criaArquivo(string arquivo)
        {
            Response.Buffer = false;
            Response.Clear();
            Response.ClearContent();
            Response.ClearHeaders();

            Response.AddHeader("Content-Disposition", "attachment; filename=" + arquivo + "_" + DateTime.Now.ToString("dd_MM_yyyy__HH_mm_ss") + ".pdf");
            Response.ContentType = "Application/pdf";
            Response.BinaryWrite(getDocumentReport(arquivo));
            Response.Flush();
            Response.End();
        }

        private byte[] getDocumentReport(string title)
        {
            MemoryStream stream = new MemoryStream();
            Document documento = new Document(PageSize.A4);
            
            PdfWriter writer = PdfWriter.GetInstance(documento, stream);

            writer.PageEvent = new PdfHandlerEvents(getTitle(title));
            documento.Open();

            DataTable dt = findDataTable(title);

            fillReport(documento, writer, dt, title);
            documento.Close();
            return stream.GetBuffer();
        }

        private DataTable findDataTable(string title)
        {
            switch (title)
            {
                case "ParcelasCaixa":
                    return new modeloCaixa().getParcelasCaixa(
                                            Session["datainicialRelatorio"].ToString(),
                                            Session["datafinalRelatorio"].ToString());
                case "CaixaConta":
                    return new modeloCaixa().getCaixaConta(
                                            Session["datainicialRelatorio"].ToString(),
                                            Session["datafinalRelatorio"].ToString(),
                                            HttpContext.Current.Session["USUARIO_ACESSO"].ToString().Equals("2") ? 99 : 
                                            Convert.ToInt32(HttpContext.Current.Session["ID_CLINICA"]));
                case "Parcelas_Pagas":
                    return new modeloParcelas().getParcelasPagasPeriodo(
                                            Session["datainicialRelatorio"].ToString(), 
                                            Session["datafinalRelatorio"].ToString(), 
                                            Session["id_clinicaRelatorio"].ToString(), 
                                            Session["id_clienteRelatorio"].ToString());
                case "Parcelas_Pagas_Clinica":
                    return new modeloParcelas().getParcelasPagasClinicaPeriodo(
                                            Session["datainicialRelatorio"].ToString(),
                                            Session["datafinalRelatorio"].ToString(),
                                            Session["id_clinicaRelatorio"].ToString(),
                                            Session["id_clienteRelatorio"].ToString());
                case "Parcelas_Atrasadas":
                    return new modeloParcelas().getParcelasAtrasadasPeriodo(
                                            Session["datainicialRelatorio"].ToString(),
                                            Session["datafinalRelatorio"].ToString(),
                                            Session["id_clinicaRelatorio"].ToString(),
                                            Session["id_clienteRelatorio"].ToString());
                case "Parcelas_Transferidas":
                    return new modeloParcelas().getParcelasTransferidasPeriodo(
                                            Session["datainicialRelatorio"].ToString(),
                                            Session["datafinalRelatorio"].ToString(),
                                            Session["id_clinicaRelatorio"].ToString(),
                                            Session["id_clienteRelatorio"].ToString());
                case "ParcelasVencer":
                    return new modeloParcelas().getParcelasVencer(
                                            Session["datainicialRelatorio"].ToString(),
                                            Session["datafinalRelatorio"].ToString(),
                                            Session["id_clinicaRelatorio"].ToString(),
                                            Session["id_clienteRelatorio"].ToString());
                case "Parcelas_Promocao":
                    return new modeloParcelas().getParcelasPromocaoPeriodo(
                                            Session["datainicialRelatorio"].ToString(),
                                            Session["datafinalRelatorio"].ToString(),
                                            Session["id_clinicaRelatorio"].ToString(),
                                            Session["id_clienteRelatorio"].ToString());
                case "Indicados":
                    return new modeloIndicado().getIndicados(
                                            Convert.ToInt32(Session["id_clienteRelatorio"]),
                                            Convert.ToInt32(Session["id_clinicaRelatorio"]),
                                            Session["datainicialRelatorio"] == null ? "" : Session["datainicialRelatorio"].ToString(),
                                            Session["datainicialRelatorio"] == null ? "" : Session["datafinalRelatorio"].ToString());

                case "Creditos":
                    return new modeloCredito().getCreditosPeriodo(
                                            Convert.ToInt32(Session["id_clienteRelatorio"]),
                                            Convert.ToInt32(Session["id_clinicaRelatorio"]),
                                            Session["datainicialRelatorio"] == null ? "" : Session["datainicialRelatorio"].ToString(),
                                            Session["datainicialRelatorio"] == null ? "" : Session["datafinalRelatorio"].ToString());

                case "Debitos":
                    return new modeloCredito().getDebitos(
                                            Convert.ToInt32(Session["id_clienteRelatorio"]),
                                            Convert.ToInt32(Session["id_clinicaRelatorio"]));

                default:
                    {
                        return new modeloProcedimentoCliente().getProcedimentoRelatorio(
                            Session["datainicialRelatorio"] == null ? "" : Session["datainicialRelatorio"].ToString(),
                            Session["datainicialRelatorio"] == null ? "" : Session["datafinalRelatorio"].ToString(),
                                                Session["id_clinicaRelatorio"].ToString(),
                                                Session["id_dentistaRelatorio"].ToString());
                    }
            }
        }

        private string getTitle(string title)
        {
            ModeloClinica mc = new ModeloClinica();
            string  clinica = Session["id_clinicaRelatorio"].ToString().Equals("-999") ? "Todas" : mc.getClinica(int.Parse(Session["id_clinicaRelatorio"].ToString())).Rows[0]["cidade"].ToString();
            
            switch (title)
            {
                case "ParcelasCaixa":
                    return "Parcelas Pagas no período referente à: " +
                        Session["datainicialRelatorio"].ToString() + " e " +
                        Session["datafinalRelatorio"].ToString();
                case "CaixaConta":
                    return "Entradas e Saídas no período referente à: " +
                        Session["datainicialRelatorio"].ToString() + " e " +
                        Session["datafinalRelatorio"].ToString();
                case "Parcelas_Pagas":
                    return "Parcelas Pagas no período referente à: " + 
                        Session["datainicialRelatorio"].ToString() + " e " + 
                        Session["datafinalRelatorio"].ToString();
                case "Parcelas_Pagas_Clinica":
                    return "Parcelas Pagas na Clínica no período referente à: " +
                        Session["datainicialRelatorio"].ToString() + " e " +
                        Session["datafinalRelatorio"].ToString();
                case "ParcelasVencer":
                    return "Próximas 100 parcelas à vencer no período referente à: " +
                        Session["datainicialRelatorio"].ToString() + " e " +
                        Session["datafinalRelatorio"].ToString() + " - Clínica: "+clinica;
                case "Parcelas_Atrasadas":
                    return "Parcelas Atrasadas no período referente à: " +
                        Session["datainicialRelatorio"].ToString() + " e " +
                        Session["datafinalRelatorio"].ToString();
                case "Parcelas_Transferidas":
                    return "Parcelas Transferidas no período referente à: " +
                        Session["datainicialRelatorio"].ToString() + " e " +
                        Session["datafinalRelatorio"].ToString();
                case "Parcelas_Promocao":
                    return "Parcelas Promocionais no período referente à: " +
                        Session["datainicialRelatorio"].ToString() + " e " +
                        Session["datafinalRelatorio"].ToString();
                case "Indicados":
                    {
                        return GetTitleEuAmoAparelho("Indicados");
                    }
                case "Creditos":
                    {
                        return GetTitleEuAmoAparelhoCreditos("Créditos");
                    }
                case "Debitos":
                    {
                        Session["datainicialRelatorio"] = "";
                        Session["datafinalRelatorio"] = "";
                        return GetTitleEuAmoAparelho("Débitos");
                    }
                default:
                    {
                        string strReturn = "Procedimentos realizados";
                        if (Session["datainicialRelatorio"] != null)
                            strReturn += " no período referente à: " + Session["datainicialRelatorio"].ToString() + " e " + Session["datafinalRelatorio"].ToString();
                        if (Session["id_clinicaRelatorio"] != null)
                            strReturn += " na clínica @c";
                        if (Session["id_dentistaRelatorio"] != null)
                            strReturn += " pelo dentista @d";

                        if (Convert.ToInt32(Session["id_clinicaRelatorio"]) == -999)
                            strReturn = strReturn.Replace("@c", "Todos");
                        else
                        {
                            DataTable dc = new ModeloClinica().getClinica(Convert.ToInt32(Session["id_clinicaRelatorio"]));
                            strReturn = strReturn.Replace("@c", dc.Rows[0]["CIDADE"].ToString());
                        }
                        if (Convert.ToInt32(Session["id_dentistaRelatorio"]) == -999)
                            strReturn = strReturn.Replace("@d", "Todos");
                        else
                        {
                            DataTable dd = new modeloDentista().getDentista(Convert.ToInt32(Session["id_dentistaRelatorio"]));
                            strReturn = strReturn.Replace("@d", dd.Rows[0]["NOME"].ToString());
                        }

                        return strReturn;
                    }
            }
        }

        private string GetTitleEuAmoAparelho(string tipo)
        {
            string str = tipo + " " +
                        (Session["datainicialRelatorio"] != null &&
                        !string.IsNullOrEmpty(Session["datainicialRelatorio"].ToString()) ?
                        "no período referente à: " + Session["datainicialRelatorio"].ToString() + " e " + Session["datafinalRelatorio"].ToString() :
                        "") + " na clínica " + (Session["id_clinicaRelatorio"].ToString().Equals("-999") ? "Todas" : "@C")
                            + " pelo paciente " + (Session["id_clienteRelatorio"].ToString().Equals("-999") ? "Todas" : "@P");
            if (str.Contains("@C"))
            {
                DataTable dc = new ModeloClinica().getClinica(Convert.ToInt32(Session["id_clinicaRelatorio"]));
                str = str.Replace("@C", dc.Rows[0]["CIDADE"].ToString());
            }
            if (str.Contains("@P"))
            {
                DataTable dc = new modeloCliente().getCliente(Convert.ToInt32(Session["id_clienteRelatorio"]));
                str = str.Replace("@P", dc.Rows[0]["NOME"].ToString());
            }
            return str;
        }

        private string GetTitleEuAmoAparelhoCreditos(string tipo)
        {
            string str = tipo + " " +
                        " na clínica " + (Session["id_clinicaRelatorio"].ToString().Equals("-999") ? "Todas" : "@C")
                            + " pelo paciente " + (Session["id_clienteRelatorio"].ToString().Equals("-999") ? "Todas" : "@P");
            if (str.Contains("@C"))
            {
                DataTable dc = new ModeloClinica().getClinica(Convert.ToInt32(Session["id_clinicaRelatorio"]));
                str = str.Replace("@C", dc.Rows[0]["CIDADE"].ToString());
            }
            if (str.Contains("@P"))
            {
                DataTable dc = new modeloCliente().getCliente(Convert.ToInt32(Session["id_clienteRelatorio"]));
                str = str.Replace("@P", dc.Rows[0]["NOME"].ToString());
            }
            return str;
        }

        private void fillReport(Document documento, PdfWriter writer, DataTable dt, string title)
        {
            int maior = -1;
            int ultimo = 0;
            if (title.ToUpper().Contains("PROCEDIMENTO"))
            {
                foreach (DataRow dr in dt.Rows)
                {
                    maior = dr["PACIENTE"].ToString().Length > maior ?
                            dr["PACIENTE"].ToString().Length : 
                            maior;
                 
                }
            }
            else //if (title.ToUpper().Contains("PARCELAS"))
            {
                foreach (DataRow dr in dt.Rows)
                {
                    foreach (DataColumn dc in dt.Columns)
                    {
                        maior = dr[dc.ColumnName].ToString().Length > maior ?
                                dr[dc.ColumnName].ToString().Length :
                                maior;
                    }
                }
            }
            
            for (int i = 0; i < Math.Round(Convert.ToDouble(dt.Rows.Count) / Convert.ToDouble(pageCount) + 0.5); ++i)
            {
                insertTabela(documento, writer, dt, i, title, maior, ref ultimo);
            }
        }

        public void insertTabela(Document documento, PdfWriter writerPdf, DataTable dt, int page, string title, int maior, ref int ultimo)
        {
            int delta = 0;

            PdfPTable table = new PdfPTable(dt.Columns.Count);

            switch (title.ToUpper())
            {
                case "PARCELASCAIXA":
                    {
                        table.SetWidthPercentage(new float[] { 40, 30, 15, 15 }, documento.PageSize);
                        break;
                    }
                case "CAIXACONTA":
                    {
                        table.SetWidthPercentage(new float[] { 20, 20, 15, 15, 30 }, documento.PageSize);
                        break;
                    }
                case "PARCELAS":
                    {
                        table.SetWidthPercentage(new float[] { 30, 20, 12, 13, 25 }, documento.PageSize);
                        if (maior != -1)
                            delta = maior / 23;
                        break;
                    }
                case "PROCEDIMENTO":
                    {
                        table.SetWidthPercentage(new float[] { 12, 25, 25, 25, 13 }, documento.PageSize);
                        if (maior != -1)
                            delta = maior / 19;
                        break;
                    }
                case "INDICADOS":
                    {
                        table.SetWidthPercentage(new float[] { 30, 30, 15, 25 }, documento.PageSize);
                        if (maior != -1)
                            delta = maior / 23;
                        break;
                    }
                //case "CREDITOS":
                //    {
                //        table.SetWidthPercentage(new float[] { 55, 15, 15, 15 }, documento.PageSize);
                //        if (maior != -1)
                //            delta = maior / 42;
                //        break;
                //    }
                case "DEBITOS":
                    {
                        table.SetWidthPercentage(new float[] { 45, 15, 40 }, documento.PageSize);
                        if (maior != -1)
                            delta = maior / 42;
                        break;
                    }
            }

            table.DefaultCell.BorderColor = iTextSharp.text.BaseColor.LIGHT_GRAY;
            table.DefaultCell.BackgroundColor = iTextSharp.text.BaseColor.GRAY;
            table.DefaultCell.Rowspan = 10;
            foreach (DataColumn dc in dt.Columns)
            {
                table.AddCell(dc.ColumnName);
            }

            table.DefaultCell.BackgroundColor = iTextSharp.text.BaseColor.WHITE;
            int multiplier = title.ToUpper().Contains("PROCEDIMENTO") ? 4 : 6;
            for (int i = ultimo, j = 0; j < (pageCount + (delta * multiplier)); ++i, ultimo++, j++)
            {
                if (dt.Rows.Count == i)
                    break;

                foreach (DataColumn dc in dt.Columns)
                {
                    Chunk strChunk = new Chunk(dt.Rows[i][dc.ColumnName].ToString(), font);

                    Phrase phrase = new Phrase(strChunk);
                    table.AddCell(new PdfPCell(phrase));
                }
                j += delta;
            }
            
            table.WidthPercentage = 100;
            table.HorizontalAlignment = Element.ALIGN_CENTER;
            documento.Add(new Paragraph(" "));
            table.SpacingBefore = 10f;
            documento.Add(table);
        }

        [WebMethod]
        public static string setInfosParcelas(string datainicial, string datafinal, int id_clinica, int id_cliente)
        {
            HttpContext.Current.Session["datainicialRelatorio"] = "";
            HttpContext.Current.Session["datafinalRelatorio"] = "";
            try
            {
                Convert.ToDateTime(datainicial);
                Convert.ToDateTime(datafinal);
            }
            catch
            {
                return "erro_data";
            }
            HttpContext.Current.Session["datainicialRelatorio"] = datainicial;
            HttpContext.Current.Session["datafinalRelatorio"] = datafinal;
            HttpContext.Current.Session["id_clinicaRelatorio"] = id_clinica;
            HttpContext.Current.Session["id_clienteRelatorio"] = id_cliente;
            return "ok";
        }

        [WebMethod]
        public static string setInfosProcedimento(string datainicial, string datafinal, int id_clinica, int id_dentista)
        {
            HttpContext.Current.Session["datainicialRelatorio"] = "";
            HttpContext.Current.Session["datafinalRelatorio"] = "";
            bool not = false;
            if (string.IsNullOrEmpty(datainicial) &&
               string.IsNullOrEmpty(datafinal))
                not = true;
            if (!not)
            {
                try
                {
                    Convert.ToDateTime(datainicial);
                    Convert.ToDateTime(datafinal);
                }
                catch
                {
                    return "erro_data";
                }
                HttpContext.Current.Session["datainicialRelatorio"] = datainicial;
                HttpContext.Current.Session["datafinalRelatorio"] = datafinal;
            }
            HttpContext.Current.Session["id_clinicaRelatorio"] = id_clinica;
            HttpContext.Current.Session["id_dentistaRelatorio"] = id_dentista;
            return "ok";
        }

        [WebMethod]
        public static string setInfosCaixa(string datainicial, string datafinal)
        {
            HttpContext.Current.Session["datainicialRelatorio"] = "";
            HttpContext.Current.Session["datafinalRelatorio"] = "";
            bool not = false;
            if (string.IsNullOrEmpty(datainicial) &&
               string.IsNullOrEmpty(datafinal))
                not = true;
            if (!not)
            {
                try
                {
                    Convert.ToDateTime(datainicial);
                    Convert.ToDateTime(datafinal);
                }
                catch
                {
                    return "erro_data";
                }
                HttpContext.Current.Session["datainicialRelatorio"] = datainicial;
                HttpContext.Current.Session["datafinalRelatorio"] = datafinal;
            }
            return "ok";
        }

        [WebMethod]
        public static string setIndicado(string datainicial, string datafinal, int id_indicou, int id_clinica, string tipo_relatorio)
        {
            bool not = false;
            HttpContext.Current.Session["datainicialRelatorio"] = "";
            HttpContext.Current.Session["datafinalRelatorio"] = ""; 
            if (tipo_relatorio.Equals("BTN_Debitos")||
                (string.IsNullOrEmpty(datainicial) &&
                string.IsNullOrEmpty(datafinal)))
                not = true;
            if (!not)
            {
                try
                {
                    Convert.ToDateTime(datainicial);
                    Convert.ToDateTime(datafinal);
                }
                catch
                {
                    return "erro_data";
                }
                HttpContext.Current.Session["datainicialRelatorio"] = datainicial;
                HttpContext.Current.Session["datafinalRelatorio"] = datafinal;
            }

            HttpContext.Current.Session["id_clinicaRelatorio"] = id_clinica;
            HttpContext.Current.Session["id_clienteRelatorio"] = id_indicou;
            return "ok";
        }
        
        protected void parcelasPagas_Click(object sender, EventArgs e)
        {
            criaArquivo("Parcelas_Pagas");
        }

        protected void BTN_ParcelasPagasClinica_Click(object sender, EventArgs e)
        {
            criaArquivo("Parcelas_Pagas_Clinica");
        }

        protected void BTN_ParcelasAtrasadas_Click(object sender, EventArgs e)
        {
            criaArquivo("Parcelas_Atrasadas");
        }

        protected void BTN_ParcelasTransferidas_Click(object sender, EventArgs e)
        {
            criaArquivo("Parcelas_Transferidas");
        }

        protected void BTN_ParcelasPromocao_Click(object sender, EventArgs e)
        {
            criaArquivo("Parcelas_Promocao");
        }

        protected void BTN_Procedimento_periodo_Click(object sender, EventArgs e)
        {
            criaArquivo("Procedimento_periodo");
        }

        protected void BTN_Procedimento_dentista_Click(object sender, EventArgs e)
        {
            criaArquivo("Procedimento_dentista");
        }

        protected void BTN_Procedimento_clinica_Click(object sender, EventArgs e)
        {
            criaArquivo("Procedimento_clinica");
        }

        protected void BTN_ParcelasCaixa_Click(object sender, EventArgs e)
        {
            criaArquivo("ParcelasCaixa");
        }

        protected void BTN_ParcelasVencer_Click(object sender, EventArgs e)
        {
            criaArquivo("ParcelasVencer");
        }

        protected void BTN_CaixaConta_Click(object sender, EventArgs e)
        {
            criaArquivo("CaixaConta");
        }

        protected void BTN_Indicados_Click(object sender, EventArgs e)
        {
            criaArquivo("Indicados");
        }

        protected void BTN_Creditos_Click(object sender, EventArgs e)
        {
            criaArquivo("Creditos");
        }

        protected void BTN_Debitos_Click(object sender, EventArgs e)
        {
            criaArquivo("Debitos");
        }
    }
}